﻿// This is the code for the BNs inference
//
//  'The second project homework for Artifical Intelligence'
// 
// Yangang Wang, 2021/11/9, @SEU
//

#include <fstream>
#include <string>
#include <regex>
#include <iostream>
using namespace std;

void main(int argc, char** argv)
{
	// read the mat
	// the missing element is indicated by -1
	//
	int Mat_missing[100][100];
	{

		ifstream infile("C:\\Users\\30666\\Desktop\\mat_missing.txt");
		if (infile.is_open()) {
			string line;
			regex term(" ");
			int lineIdx = 0;
			while (!infile.eof()) {
				if (lineIdx >= 100) break;
				getline(infile, line);
				sregex_token_iterator it(line.begin(), line.end(), term, -1);
				sregex_token_iterator end;
				for (int i = 0; it != end; it++, i++) {
					string str = *it;
					Mat_missing[lineIdx][i] = atoi(str.c_str());
				}
				lineIdx++;
			}
			infile.close();
		}
	}

	//======================
	// please fill the following code by Bayes Network training and inference
	//
	// Yangang Wang, 2021/11/9, @SEU
	//

	// (1) todo...

	// 定义 x,y 横纵坐标为特征
	// [0,10] 11个值为类别
	//计算先验概率

	int Ny[11] = { 0 };
	int n = 100;				// 特征可取的值,横纵坐标值
	int X[100][11] = { 0 };			// 横坐标
	int Y[100][11] = { 0 };			// 纵坐标

	int N = 0;				// 样本个数
	int k = 11;				// 类别
	for (int i = 0; i < 100; i++)
	{
		for (int j = 0; j < 100; j++)
		{
			if (Mat_missing[i][j] == -1) {
				continue;
			}
			else {
				Ny[Mat_missing[i][j]] += 1;
				N =N+1;
				X[i][Mat_missing[i][j]] += 1;  // 横坐标相加
				Y[j][Mat_missing[i][j]] += 1;// 纵坐标相加
			}
		}
	}

	// 计算pyi
	double pY[11] = { 0 };
	cout << "  N:  " << N << endl;
	for (int i = 0; i < k; i++) {
		pY[i] = double(Ny[i]) / double(N );
		cout << "  Ny" << i << " = " << Ny[i] << endl;
		cout << "  Py" << i << " = " << pY[i] << endl;
	}
    //输出
	cout << "横坐标: " << endl;
	for (int i = 0; i < 100; i++) {
		for (int j = 0; j < k; j++) {
			cout << X[i][j] << ' ';
		}
		cout << endl;
	}
	cout << endl << "纵坐标: " << endl;
	for (int i = 0; i < 100; i++) {
		for (int j = 0; j < k; j++) {
			cout << Y[i][j] << ' ';
		}
		cout << endl;

	}

	//======================
	// You can compare the result with groudtruth data
	// read the groudtruth data
	int Mat_gd[100][100];
	{
		ifstream infile("C:\\Users\\Administrator\\Desktop\\2\\mat_groudtruth.txt");
		if (infile.is_open()) {
			string line;
			regex term(" ");
			int lineIdx = 0;
			while (!infile.eof()) {
				if (lineIdx >= 100) break;
				getline(infile, line);
				sregex_token_iterator it(line.begin(), line.end(), term, -1);
				sregex_token_iterator end;
				for (int i = 0; it != end; it++, i++) {
					string str = *it;
					Mat_gd[lineIdx][i] = atoi(str.c_str());
				}
				lineIdx++;
			}
			infile.close();
		}
	}
	// fill the comparing code here
	//
	// Yangang Wang, 2021/11/9, @SEU
	//

	// infer and comp
	int a = 0;  //正确
	int b = 0;  //错误
	for (int i = 0; i < 100; i++)
	{
		for (int j = 0; j < 100; j++)
		{
			if (Mat_missing[i][j] == -1) {

				double P = 0;
				for (int s = 0; s < k; s++)
				{

					double temp = pY[s] * (X[i][s]) / (Ny[s] ) * (Y[j][s] ) / (Ny[s] );

					if (temp > P)
					{
						P = temp;
						Mat_missing[i][j] = s;
					}
				}
				if (Mat_missing[i][j] == Mat_gd[i][j])
				{
					a+= 1;
				}
				else
				{
					b += 1;
					cout << "x= " << i << '\t' << "y= " << j << endl;
					cout << "ground truth: " << Mat_gd[i][j] << endl;
					cout << "predict: " << Mat_missing[i][j] << endl;
					for (int s = 0; s < k; s++)
					{
						double temp = pY[s] * (X[i][s]) / (Ny[s] ) * (Y[j][s] ) / (Ny[s] );
						cout << "f" << s << ": " << temp << "  ";
					}
					cout << endl;
				}
			}
		}
	}
	cout << "a=" << a << "\t" << "b=" << b << endl;

}